// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Direction_3.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Direction_3.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================

#include <CGAL/basic.h>
#include <include/Kernels.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>

const char* Direction_3_doc[] ={
"An object of the class Direction_3 is a vector in the three-dimensional vector space\n\
where we forget about their length. They can be viewed as unit vectors, \n\
although there is no normalization internally, since this is error prone. \n\
Directions are used whenever the length of a vector does not matter. \n\
They also characterize a set of parallel lines that have the same orientation or \n\
the direction normal to parallel planes that have the same orientation. \n\
For example, you can ask for the direction orthogonal to an oriented plane, or \n\
the direction of an oriented line.\n\
For more details see a C++ doc:\n\
http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Kernel_23_ref/Class_Direction_3.html",

"d = Direction_3( Vector_3 v)\n\
introduces a direction d initialised with the direction of vector v.\n\n\
d = Direction_3( Line_3 l)\n\
introduces the direction d of line l.\n\n\
d = Direction_3( Ray_3<Kernel> r)\n\
introduces the direction d of ray r.\n\n\
d = Direction_3( Segment_3 s)\n\
introduces the direction d of segment s.\n\n\
d = Direction_3( x, y, z)\n\
introduces a direction d initialised with the direction from the origin \n\
to the point with Cartesian coordinates (x, y, z).",

"d.vector(self) -> Vector_3\nreturns a vector that has the same direction as d.",

"d.transform(self,Aff_transformation_3 t) -> Direction_3\nreturns the direction obtained by applying t on d.",

"delta(self,int i) ->double\nreturns values, such that d== Direction_3(delta(0),delta(1),delta(2)).\n\
Precondition: : 0 <= i <= 2 ",

"d.dx(self) ->  returns delta(0).",
"d.dy(self) ->  returns delta(1).",
"d.dz(self) ->  returns delta(2)."
};

template<class Direction_3>
boost::python::str py_repr_Direction_3(const Direction_3& d )
{
	using namespace boost::python;
	return str("Direction_3("+ str(d.dx()) +","+ str(d.dy()) + "," + str(d.dz()) +")" );
}


template <class kernel > 
void Py_Direction_3()
{
	typedef typename kernel::Segment_3 						Segment_3;
 	typedef typename kernel::Vector_3 						Vector_3;
 	typedef typename kernel::Direction_3 						Direction_3;
 	typedef typename kernel::Line_3 						Line_3;
  	typedef typename kernel::Ray_3 						        Ray_3;
	typedef typename kernel::FT 							FT;

	using namespace boost::python;

        class_< Direction_3 >("Direction_3", Direction_3_doc[0], init<>())
        .def(init< const Direction_3& >(Direction_3_doc[1]))
        .def(init< const Vector_3& >())
        .def(init< const Line_3& >())
        .def(init< const Ray_3& >())
        .def(init< const Segment_3& >())
        .def(init< const FT&, const FT&, const FT& >())
        .def(init< const double&, const double&, const double& >())
        .def("vector", &Direction_3::vector, Direction_3_doc[2])
        .def("transform", &Direction_3::transform, Direction_3_doc[3])
#if CGAL_VERSION_NR < 1030301000
        .def("delta", &Direction_3::delta, by_cref(), Direction_3_doc[4])
        .def("dx", &Direction_3::dx, by_cref(), Direction_3_doc[5])
        .def("dy", &Direction_3::dy, by_cref(), Direction_3_doc[6])
        .def("dz", &Direction_3::dz, by_cref(), Direction_3_doc[7])
#else
        .def("delta", &Direction_3::delta, typename Value_or_cref<typename kernel::Compute_dx_3, Direction_3 > ::type(), Direction_3_doc[4])
        .def("dx", &Direction_3::dx, typename Value_or_cref<typename kernel::Compute_dx_3, Direction_3 > ::type(), Direction_3_doc[5])
        .def("dy", &Direction_3::dy, typename Value_or_cref<typename kernel::Compute_dy_3, Direction_3 > ::type(), Direction_3_doc[6])
        .def("dz", &Direction_3::dz, typename Value_or_cref<typename kernel::Compute_dz_3, Direction_3 > ::type(), Direction_3_doc[7])
#endif
	.def("__repr__", &py_repr_Direction_3<Direction_3>)
        .def( self == self )
        .def( self != self )
        .def( -self )
    ;
}


void export_Direction_3()
{
	Py_Direction_3<K>();
}
